"""A collection of all commands that a Kanna can use to interact with the game."""

from src.common import config, settings, utils
import time
import math
from src.routine.components import Command
from src.common.vkeys import press, key_down, key_up


# List of key mappings
class Key:
    # Movement
    JUMP = 'c'
    # Buffs


    # Skills
    主攻 = 'a'
    瞬移 = 's'
    解放宝珠 = 'd'
    光与暗的洗礼 = 'f'
    混沌共鸣 = 'g'
    真理之門 = 'q'
    重启平衡 = 'w'
    死亡镰刀 = 'e'
    末日审判 = 'r'
    暗黑烈焰 = 'e'
    創世紀 = 'f12'

#########################
#       Commands        #
#########################
def step(direction, target):
    """
    Performs one movement step in the given DIRECTION towards TARGET.
    Should not press any arrow keys, as those are handled by Auto Maple.
    """

    num_presses = 2
    if direction == 'up' or direction == 'down':
        num_presses = 1
    if config.stage_fright and direction != 'up' and utils.bernoulli(0.75):
        time.sleep(utils.rand_float(0.1, 0.3))
    d_y = target[1] - config.player_pos[1]
    if abs(d_y) > settings.move_tolerance * 1.5:
        if direction == 'down':
            press(Key.JUMP, 3)
        elif direction == 'up':
            press(Key.JUMP, 1)
    press(Key.瞬移, num_presses)
    press(Key.主攻,1)

class Adjust(Command):
    """Fine-tunes player position using small movements."""

    def __init__(self, x, y, max_steps=5):
        super().__init__(locals())
        self.target = (float(x), float(y))
        self.max_steps = settings.validate_nonnegative_int(max_steps)

    def main(self):
        counter = self.max_steps
        toggle = True
        error = utils.distance(config.player_pos, self.target)
        while config.enabled and counter > 0 and error > settings.adjust_tolerance:
            if toggle:
                d_x = self.target[0] - config.player_pos[0]
                threshold = settings.adjust_tolerance / math.sqrt(2)
                if abs(d_x) > threshold:
                    walk_counter = 0
                    if d_x < 0:
                        key_down('left')
                        while config.enabled and d_x < -1 * threshold and walk_counter < 60:
                            time.sleep(0.05)
                            walk_counter += 1
                            d_x = self.target[0] - config.player_pos[0]
                        key_up('left')
                    else:
                        key_down('right')
                        while config.enabled and d_x > threshold and walk_counter < 60:
                            time.sleep(0.05)
                            walk_counter += 1
                            d_x = self.target[0] - config.player_pos[0]
                        key_up('right')
                    counter -= 1
            else:
                d_y = self.target[1] - config.player_pos[1]
                if abs(d_y) > settings.adjust_tolerance / math.sqrt(2):
                    if d_y < 0:
                        瞬移('up').main()
                    else:
                        key_down('down')
                        time.sleep(0.05)
                        press(Key.JUMP, 3, down_time=0.1)
                        key_up('down')
                        time.sleep(0.05)
                    counter -= 1
            error = utils.distance(config.player_pos, self.target)
            toggle = not toggle


class Buff(Command):
    """Uses each of Kanna's buffs once. Uses 'Haku Reborn' whenever it is available."""

    def __init__(self):
        super().__init__(locals())
        self.buff_time = 0

        self.skill_1 = 0
        self.skill_2 = 0
        self.skill_3 = 0
        self.skill_4 = 0
        self.skill_5 = 0
        self.skill_6 = 0
        self.skill_7 = 0

    def main(self):
        buffs = ['f1','f2','f3','f4','f5']
        # now = time.time()
        # if self.skill_1 == 0 or now - self.skill_1 > 12:
        #     # press('q',1)
        #     self.skill_1 = now
        # if self.skill_2 == 0 or now - self.skill_2 > 6:
        #     press('d',1)
        #     self.skill_2 = now
        # if self.skill_3 == 0 or now - self.skill_3 > 120:
        #     # press('7',1)
        #     # press('1',1)
        #     # self.skill_3 = now
        #     pass
        # if self.skill_4 == 0 or now - self.skill_4 > 45:
        #     press('2', 1)
        #     self.skill_4 = now
        # if self.skill_5 == 0 or now - self.skill_5 > 30:
        #     press('3', 1)
        #     self.skill_5 = now
        # if self.skill_6 == 0 or now - self.skill_6 > 180:
        #     press('4', 2)
        #     self.skill_6 = now
        # if self.skill_7 == 0 or now - self.skill_7 > 180:
        #     press('5', 1)
        #     self.skill_7 = now
        # if self.buff_time == 0 or now - self.buff_time > settings.buff_cooldown:
        #     for key in buffs:
        #         press(key, 3, up_time=0.3)
        #     self.buff_time = now

class 末日审判(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=120):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.末日审判]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 死亡镰刀(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=10):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.死亡镰刀]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 暗黑烈焰(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=5):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.暗黑烈焰]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 重启平衡(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=150):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.重启平衡]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 解放宝珠(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=180):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.解放宝珠]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 光与暗的洗礼(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=45):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.光与暗的洗礼]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 混沌共鸣(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=30):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.混沌共鸣]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 真理之門(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=30):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.真理之門]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 創世紀(Command):
    """Uses 'Tengu Strike' once."""

    def __init__(self, duration=30):
        super().__init__(locals())
        self.duration = settings.validate_nonnegative_int(duration)
        self.time = 0

    def main(self):
        kills = [Key.創世紀]
        now = time.time()
        if self.time == 0 or now - self.time > self.duration:
            for key in kills:
                press(key, 2, up_time=0.3)
            self.time = now

class 瞬移(Command):
    """
    Teleports in a given direction, jumping if specified. Adds the player's position
    to the current Layout if necessary.
    """

    def __init__(self, direction, jump='False'):
        super().__init__(locals())
        self.direction = settings.validate_arrows(direction)
        self.jump = settings.validate_boolean(jump)

    def main(self):
        num_presses = 3
        time.sleep(0.05)
        if self.direction in ['up', 'down']:
            num_presses = 2
        if self.direction != 'up':
            key_down(self.direction)
            time.sleep(0.05)
        if self.jump:
            if self.direction == 'down':
                press(Key.JUMP, 3, down_time=0.1)
            else:
                press(Key.JUMP, 1)
        if self.direction == 'up':
            key_down(self.direction)
            time.sleep(0.05)
        press(Key.瞬移, num_presses)
        key_up(self.direction)
        if settings.record_layout:
            config.layout.add(*config.player_pos)


